package com.wmyg.antifake.controller;

import com.wmyg.antifake.dto.RecordDto;
import com.wmyg.antifake.entity.Factory;
import com.wmyg.antifake.entity.Product;
import com.wmyg.antifake.entity.ProductOrigin;
import com.wmyg.antifake.entity.Record;
import com.wmyg.antifake.service.RecordService;
import com.wmyg.antifake.utils.CodeImageUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.Principal;
import java.util.Date;

/**
 * @author 王卓逸
 * @program TODO
 * @description TODO
 * @create 2019-05-20
 */
@Slf4j
@RestController
@RequestMapping(value = "/record")
public class RecordController {

    @Autowired
    RecordService recordService;

    @Autowired
    RedisTemplate redisTemplate;

    @PreAuthorize("hasAuthority('createcode')")
    @PostMapping(value = "/record")
    public Integer saveRecord(RecordDto recordDto) {
        Record record = new Record();
        Product product = new Product();
        product.setProductId(recordDto.getProductId());
        record.setProduct(product);
        Integer total = 0;
        if (null != recordDto.getFactoryId() && recordDto.getFactoryId() != 0) {
            Factory factory = new Factory();
            factory.setFactoryId(recordDto.getFactoryId());
            record.setFactory(factory);
        }
        if (null != recordDto.getOriginId() && recordDto.getOriginId() != 0) {
            ProductOrigin origin = new ProductOrigin();
            origin.setOriginId(recordDto.getOriginId());
            record.setOrigin(origin);
        }
        // if (null != recordDto.getEnterCase()) {
        if ( 0 != recordDto.getEnterCase()) {

            log.info("Case : {}", recordDto.getEnterCase());
            record.setEnterCase(recordDto.getEnterCase());
            total += recordDto.getEnterCase();
            //if (null != recordDto.getEnterBox()) {
            if ( 0 != recordDto.getEnterBox()) {
                record.setEnterBox(recordDto.getEnterBox());
                record.setTotalBox(recordDto.getEnterCase() * recordDto.getEnterBox());
                total += record.getTotalBox();
                // if (null != recordDto.getEnterPack()) {
                if ( 0 != recordDto.getEnterPack()) {

                    record.setEnterPack(recordDto.getEnterPack());
                    record.setTotalPack(recordDto.getEnterCase() * recordDto.getEnterBox() * recordDto.getEnterPack());
                    total += record.getTotalPack();
                } else {
                    record.setEnterPack(0);
                    record.setTotalPack(0);
                }
            } else {
                record.setEnterBox(0);
                record.setTotalBox(0);
                record.setEnterPack(0);
                record.setTotalPack(0);
            }
        } else {
            record.setEnterCase(0);
            log.info("Box : {}", recordDto.getEnterBox());
            //  if (null != recordDto.getEnterBox()) {
            if ( 0 != recordDto.getEnterBox()) {
                record.setEnterBox(recordDto.getEnterBox());
                record.setTotalBox(recordDto.getEnterBox());
                total += record.getTotalBox();
                // if (null != recordDto.getEnterPack()) {
                if ( 0 != recordDto.getEnterPack()) {
                    record.setEnterPack(recordDto.getEnterPack());
                    record.setTotalPack(recordDto.getEnterBox() * recordDto.getEnterPack());
                    total += record.getTotalPack();
                } else {
                    record.setEnterPack(0);
                    record.setTotalPack(0);
                }
            } else {
                log.info("Pack : {}", recordDto.getEnterPack());
                record.setEnterBox(0);
                record.setTotalBox(0);
                // if (null != recordDto.getEnterPack()) {
                if ( 0 != recordDto.getEnterPack()) {
                    record.setEnterPack(recordDto.getEnterPack());
                    record.setTotalPack(recordDto.getEnterPack());
                    total += record.getTotalPack();
                } else {
                    record.setEnterPack(0);
                    record.setTotalPack(0);
                }
            }
        }
        record.setTotal(total);
        return recordService.saveRecord(record);
    }

    @PreAuthorize("hasAuthority('createcode') or hasAuthority('code')")
    @GetMapping(value = "/record")
    public Record getRecord(Integer recordId) {
        return recordService.getRecord(recordId);
    }

    @PreAuthorize("hasAuthority('createcode') or hasAuthority('code')")
    @GetMapping(value = "/wxpay") //, produces = MediaType.IMAGE_JPEG_VALUE)
    public String wxPay(Integer recordId, HttpServletRequest request) {
//        ByteArrayOutputStream out = new ByteArrayOutputStream();
//        try {
//            ImageIO.write(CodeImageUtil.createQRPic(recordService.wxPayPre(recordId, request.getHeader("client-ip")), 2), "jpeg", out);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return out.toByteArray();
        return recordService.wxPayPre(recordId, request.getHeader("client-ip"));
    }

    @PreAuthorize("hasAuthority('createcode') or hasAuthority('code')")
    @GetMapping(value = "/alipay") //, produces = MediaType.IMAGE_JPEG_VALUE)
    public String aliPay(Integer recordId) {
//        ByteArrayOutputStream out = new ByteArrayOutputStream();
//        try {
//            ImageIO.write(CodeImageUtil.createQRPic(recordService.aliPayPre(recordId), 2), "jpeg", out);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return out.toByteArray();
        return recordService.aliPayPre(recordId);
    }

    @PreAuthorize("hasAuthority('createcode') or hasAuthority('code')")
    @GetMapping(value = "/progress")
    public Integer getProgress(Integer recordId) {
        String key = "RecordProgress" + recordId;
        if (redisTemplate.hasKey(key)) {
            return (Integer)redisTemplate.opsForValue().get(key);
        } else {
            return -1;
        }
    }

//    @PreAuthorize("hasAuthority('createcode') or hasAuthority('code')")
    @GetMapping("/downloadFile")
    public void downloadFile(String fileName, String suffix, String username, HttpServletResponse response) {
        String downloadFilePath = "/mnt/files/excel/" + fileName;//被下载的文件在服务器中的路径,
        File file = new File(downloadFilePath);
        if (file.exists()) {
            response.setContentType("application/force-download");// 设置强制下载不打开            
            response.addHeader("Content-Disposition", "attachment;fileName=" + fileName + "." + suffix);
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream outputStream = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    outputStream.write(buffer, 0, i);
                    i = bis.read(buffer);
                }

//                return "下载成功";
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                recordService.download(fileName, username);
            }
        }
    }

    @PreAuthorize("hasAuthority('code')")
    @GetMapping(value = "/recordpage")
    public Page<Record> getRecordPage(Principal principal, Integer index, String query, Date startTime, Date endTime, Integer state) {
        return recordService.getRecordPage(principal.getName(), index, query, startTime, endTime, state);
    }

    @PreAuthorize("hasAuthority('createcode') or hasAuthority('code')")
    @DeleteMapping(value = "/cancel")
    public Boolean cancelRecord(Integer recordId) {
        recordService.cancelRecord(recordId);
        return true;
    }

    @GetMapping(value = "/nonpay")
    public Boolean createCodeWithoutPay(Integer recordId) {
        recordService.produceCode(recordId);
        return true;
    }

}
